package com.googlecode.mhtetris.tetris
{
	import away3d.containers.ObjectContainer3D;
	import away3d.primitives.Cube;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.filters.GlowFilter;

	/**
	 * représente une forme : un groupe de block
	 */
	public class GBlock extends ObjectContainer3D
	{
		/* --- attributs privées --- */
		private var _lesBlocks:Array;
		
		/**
		 * grille sur laquelle est présent le block
		 */
		private var grille:Tetris3D;
		
		private var _container:ObjectContainer3D;
		
		/**
		 * type de bloc : chaine de trois caractères indiquant l'orientation des trois blocs suivant le premier
		 */
		private var type:String;
		
		/**
		 * largeur en blocs de la forme courange
		 */
		private var _blockWidth:int;
		
		/**
		 * hauteur en blocs de la forme courante
		 */
		private var _blockHeight:int;
		
		/**
		 * position dans la grille en nombre de cases (abscisse)
		 */
		private var _posX:int;
		
		/**
		 * position dans la grille en nombre de cases (ordonnée)
		 */
		private var _posY:int;
		
		private var _posDebX:int;
		
		private var _posDebY:int;
		
		/* --- constructeurs --- */
		
		/**
		 * construit une forme à partir d'une suite de caractère
		 * U : UP
		 * D : DOWN
		 * R : RIGHT
		 * L : LEFT
		 */
		public function GBlock(hash:String, _grille:Tetris3D)
		{
			
			_posX = _posY = 0;
			
			_lesBlocks = new Array();
			
			type = hash;
			
			this.grille = _grille;
			
			construct(hash);
			
		}
		
		/* --- getters & setters --- */
		
		/**
		 * tableau représentant les 4 blocs utilisés pour faire la forme
		 */
		public function get lesBlocks():Array
		{
			return _lesBlocks;
		}

		/**
		 * container dans lequel est dessiné la forme
		 * (utile pour repositionner la forme sans toucher les blocs)
		 */
		public function get container():ObjectContainer3D
		{
			return _container;
		}

		/**
		 * retourne le type du block
		 */
		public function getType():String {
			return type;
		}
		
		/**
		 * retourne la largeur en bloc de la forme courante
		 */
		public function get blockWidth():int {
			return _blockWidth;
		}
		
		/**
		 * retourne la hauteur en bloc de la forme courante
		 */
		public function get blockHeight():int {
			return _blockHeight;
		}
		
		public function get posX():int {
			return _posX;
		}
		
		public function get posY():int {
			return _posY;
		}
		
		public function set posX(position:int):void {
			_posX = position;
		}
		
		public function set posY(position:int):void {
			_posY = position;
		}
		
		/* --- fonctions --- */
		
		public function rotateBloc():void {
			//container.rotation += 90;
			// on reconstruit le hash apres rotation de 90 degrés
			var newHash:String = "";
			for (var i:int = 0; i < type.length; i++ ) {
				switch (type.charAt(i).toUpperCase()) {
					case 'L':
						// LEFT => DOWN
						newHash += type.charAt(i) == type.charAt(i).toUpperCase() ? "D" : "d";
						break;
					case 'U':
						// UP => LEFT
						newHash += type.charAt(i) == type.charAt(i).toUpperCase() ? "L" : "l";
						break;
					case 'R':
						// RIGHT => UP
						newHash += type.charAt(i) == type.charAt(i).toUpperCase() ? "U" : "u";
						break;
					case 'D':
						// DOWN => RIGHT
						newHash += type.charAt(i) == type.charAt(i).toUpperCase() ? "R" : "r";
						break;
				}
			}
			
			
			//this.removeChild(_container);
			if (grille.grille.canRotate(this, newHash)) {
				type = newHash;
				
				/*for each (var bloc:Block in lesBlocks) {
					if (bloc.parent) {
						_container.removeChild(bloc);					
						bloc = null;
					}
				}*/
				construct(newHash);				
			}
			
		}
		
		public function removeAllChildrenRecursivly(obj:ObjectContainer3D):void {
			while (obj.numChildren > 0) {
				var child:ObjectContainer3D = obj.getChildAt(0);
				removeAllChildrenRecursivly(child);
				
				if (child is Block) {
					(child as Block).deleteCube();
					(child as Block).cube = null;
				}
				
				child.parent.removeChild(child);
				child = null;
			}
		}
		
		private function construct(hash:String):void {
			
			
			if (_container) {
				//var obj:ObjectContainer3D = _container.getChildAt(0);
				/*while (_container.numChildren > 0) {
					var obj:ObjectContainer3D = _container.getChildAt(0);
					
					// on supprimer les enfants de l'objet
					while (obj.numChildren > 0) {
						obj.removeChild(obj.getChildAt(0));
					}					
					_container.removeChild(obj);
					obj = null;
				}*/
				removeAllChildrenRecursivly(_container);
			}
			
			_container = new ObjectContainer3D();
			_lesBlocks = [];
			
			
			// on créé le premier bloc
			var b:Block = new Block(Tetris3D.LARGEUR_BLOCK_PX);				
			lesBlocks.push(b);
			_container.addChild(b);
			
			var currentX:int = 0;
			var currentY:int = 0;
			
			var coordX:int = 0;
			var coordY:int = 0;
			
			var limiteDroite:int = 1;
			var limiteGauche:int = 0;
			var limiteHaute:int = 0;
			var limiteBasse:int = 1;
			
			_posDebX = _posDebY = 0;
			
			for (var i:int = 0; i < type.length; i++) {
				var c:String = hash.substr(i, 1).toUpperCase();
				
				switch (c) {
					case 'L':
						currentX -= Tetris3D.LARGEUR_BLOCK_PX;
						/* pour le calcul de la largeur */
						coordX--;
						if (coordX < limiteGauche ) {
							// on repousse la limite gauche;
							limiteGauche = coordX;
							_container.x += Tetris3D.LARGEUR_BLOCK_PX;
						}
						break;
					case 'U':
						currentY -= Tetris3D.LARGEUR_BLOCK_PX;
						/* pour le calcul de la hauteur */
						coordY--;
						if (coordY < limiteHaute) {
							// on repousse la limite haute
							limiteHaute = coordY;
							_container.y += Tetris3D.LARGEUR_BLOCK_PX;
						}
						break;
					case 'R':
						currentX += Tetris3D.LARGEUR_BLOCK_PX;
						/* pour le calcul de la largeur */
						coordX++;
						if (coordX+1 > limiteDroite) {
							_container.x -= Tetris3D.LARGEUR_BLOCK_PX;
							limiteDroite = coordX+1;
						}
						break;
					case 'D':
						currentY += Tetris3D.LARGEUR_BLOCK_PX;
						/* pour le calcul de la hauteur */
						coordY++;
						if (coordY+1 > limiteBasse) {
							_container.y -= Tetris3D.LARGEUR_BLOCK_PX;
							limiteBasse = coordY+1;
						}
						break;
				}
				
				if (c == hash.charAt(i)) {
					// c'est une majuscule, on construit le bloc
					b = new Block(Tetris3D.LARGEUR_BLOCK_PX);
					lesBlocks.push(b);
					
					b.x = currentX;
					b.y = currentY;
					
					_container.x = 0;//_posX * grille.LARGEUR_BLOCK_PX;
					_container.y = 0;//_posY * grille.HAUTEUR_GRILLE_PX;
					
					_container.addChild(b);
				}
				
			}
			
			this.addChild(_container);
			
			/*var filter:GlowFilter = new GlowFilter(0x770000, 1, 2, 2, 70, 10, true);
			container.filters = [filter];*/
			
			var oldBlockWidth:int 	= _blockWidth;
			var oldBlockHeight:int 	= _blockHeight;
			
			_blockWidth = limiteDroite-limiteGauche;
			_blockHeight = limiteBasse-limiteHaute;
			
			  
		}
		
		
	}
}